/**
 * Desenvolvido pela Fábrica de Software do CESUPA.
 * Todos os direitos reservados.
 */
package br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.services;

import br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.HelpSummaryWriter;
import br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.HelpIndexer;
import br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.HelpSummaryParser;
import br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.entities.HelpSet;
import br.cesupa.fabsoft.nomedoprojeto.modules.helpmodule.entities.HelpTopic;
import br.cesupa.fabsoft.nomedoprojeto.utils.ApplicationTools;
import br.cesupa.fabsoft.nomedoprojeto.utils.FileUtils;
import br.cesupa.fabsoft.nomedoprojeto.utils.TextUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * Manage business logic around in help module.
 *
 * @author Breno Leite
 */
public class HelpService {

    public static final String DEFAULT_HELP_CONTENT_DIRECTORY = "help/help-content/";
    public static final String PAGE_EXTENSION_MAPPING = ".jsf";
    public static final String WEB_FOLDER_NAME = "web";
    public static final String DEFAULT_INDEXES_DIRECTORY = "help/help-meta-inf/indexes/";
    public static final String HELPSETS_SUMMARY_FILE = "help/helpsets-summary.xml";
    private HelpSummaryParser helpParser = new HelpSummaryParser();
    private List<HelpTopic> helpTopics = new ArrayList<HelpTopic>();

    public HelpService() {
    }

    public HelpSet getTableOfContents() {
        if (getHelpSetsSummaryFile().exists()) {
            System.out.println("loading....");
            return helpParser.loadHelpSetsFromSummaryFile(getHelpSetsSummaryFile());
        } else {
            HelpSet helpSet = helpParser.loadHelpSetsFromDirectory(getHelpContentDirectory());
            new HelpSummaryWriter().generateHelpSetSummaryFile(helpSet);
            return helpSet;
        }
    }

    public static List<String> getAcceptedHelpExtensions() {
        List<String> acceptedExtensions = new ArrayList<String>();
        acceptedExtensions.add("xhtml");
        return acceptedExtensions;
    }

    public void checkIndexes() {
        HelpIndexer helpIndexer = new HelpIndexer();

        if (!getHelpIndexDirectory().exists()) {
            getHelpContentDirectory().mkdirs();
            helpIndexer.indexDefaltDirectory();
        } else {
            if (getHelpIndexDirectory().listFiles().length == 0) {
                helpIndexer.indexDefaltDirectory();
            }
        }
    }

    public void checkHelpSetSummaryFile() {
        if (getHelpSetsSummaryFile() == null ||
                !getHelpSetsSummaryFile().exists()) {
            new HelpSummaryWriter().generateHelpSetSummaryFile(getTableOfContents());
        }
    }

    public List<HelpTopic> getHelpTopics() {
        iterateHelpSet(getTableOfContents());
        return helpTopics;
    }

    public static List<String> getFilePath(List<String> path, File targetFile) {
        File parent = targetFile.getParentFile();
        if (!parent.getName().equals(HelpService.WEB_FOLDER_NAME)) {
            path.add(parent.getName());
            getFilePath(path, parent);
        }

        return path;
    }

    /**
     * Parse a help file in order to fill a {@link HelpTopic} object.
     *
     * @param file the target file
     * @return a help topic
     */
    public static HelpTopic retriveFileInfo(File file) {
        HelpTopic helpEntry = new HelpTopic();

        String temp = "";
        List<String> path = getFilePath(new ArrayList<String>(), file);
        for (int i = path.size() - 1; i >= 0; i--) {
            temp += path.get(i) + "/";
        }
        String filePath = "/" + temp +
                FileUtils.extractSimpleNameFromFileName(file.getName()) +
                HelpService.PAGE_EXTENSION_MAPPING;
//        helpEntry.setPath(FacesContext.getCurrentInstance().
//                getExternalContext().getRequestContextPath() + filePath);
        helpEntry.setPath(filePath);

        try {
            helpEntry.setContent(TextUtils.stripTags(FileUtils.readFile(file)));
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        if (helpEntry.getContent() != null) {
            try {
                SAXReader reader = new SAXReader();
                Document document = reader.read(file);

                Element root = document.getRootElement();

                for (Object rootChild : root.elements()) {
                    Element rootChildElement = (Element) rootChild;
                    if (rootChildElement.getName().startsWith("composition")) {
                        for (Object compositionChildObject : rootChildElement.elements()) {
                            Element paramChildElement = (Element) compositionChildObject;
                            if (paramChildElement.getName().startsWith("param")) {
                                if (paramChildElement.attributeValue("name").equals("pagetitle")) {
                                    helpEntry.setTitle(paramChildElement.attributeValue("value"));
                                }

                                if (paramChildElement.attributeValue("name").equals("pagedescription")) {
                                    helpEntry.setDescription(paramChildElement.attributeValue("value"));
                                }

                                if (paramChildElement.attributeValue("name").equals("pagekeywords")) {
                                    helpEntry.setKeywords(paramChildElement.attributeValue("value"));
                                }
                            }
                        }
                    }
                }

            } catch (DocumentException exception) {
                exception.printStackTrace();
            }
        }
        return helpEntry;
    }

    private void iterateHelpSet(HelpSet targetHelpSet) {
        helpTopics.addAll(targetHelpSet.getHelpTopics());
        iterateHelpSet(targetHelpSet);
    }

    public static File getHelpSetsSummaryFile() {
        return new File(ApplicationTools.getDirectoryInApplication(
                HelpService.HELPSETS_SUMMARY_FILE));
    }

    public static File getHelpContentDirectory() {
        return new File(ApplicationTools.getDirectoryInApplication(
                HelpService.DEFAULT_HELP_CONTENT_DIRECTORY));
    }

    public static File getHelpIndexDirectory() {
        return new File(ApplicationTools.getDirectoryInApplication(
                HelpService.DEFAULT_INDEXES_DIRECTORY));
    }
}
